package javase.annotations.processors;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import javase.annotations.annotated.AnnotatedChild;
import javase.annotations.annotated.AnnotatedParent;

public class GeneralAnnotationProcessor {
	public static void printAllClassLevelAnnotations(Class<?> clazz) {
		System.out.println("Class level annotations for class " + clazz.getSimpleName());
		Annotation [] annotations = clazz.getAnnotations();
		printAnnotations(annotations);
		System.out.println("");
	}

	private static void printAnnotations(Annotation[] annotations) {
		for(Annotation annotation : annotations) {
			String annotationName = annotation.annotationType().getSimpleName();//annotation.getClass().getSimpleName();
			System.out.println("@" + annotationName);
		}
	}
	
	public static void printAllMethodLevelAnnotations(Class<?> clazz) {
		System.out.println("Method level annotations for class " + clazz.getSimpleName());
		Method [] methods = clazz.getMethods();
		for(Method method : methods) {
			System.out.println("Method " + method.getName());
			Annotation [] annotations = method.getAnnotations();
			printAnnotations(annotations);
			System.out.println("");
		}
	}
	
	public static void printFieldLevelAnnotations(Class<?> clazz) {
		System.out.println("Field level annotations for class " + clazz.getSimpleName());
		Field [] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			System.out.println("Field " + field.getName());
			printAnnotations(field.getAnnotations());
			System.out.println("");
		}
	}
	
	public static void printAllAnnotationsForAnnotatedClass() {
		Class<AnnotatedParent> clazz = AnnotatedParent.class;
		System.out.println("Annotations general info");
		printAllClassLevelAnnotations(clazz);
		printFieldLevelAnnotations(clazz);
		printAllMethodLevelAnnotations(clazz);
		System.out.println("");
		System.out.println("Annotation details");
		MethodRuntimeAnnotationProcessor methodRuntimeAnnotationProcessor = new MethodRuntimeAnnotationProcessor();
		methodRuntimeAnnotationProcessor.printAnnotationDetails(clazz);
	}
	
	private static void checkIneritedAnnotation() {
		System.out.println("Checking inherited annotations.");
		printAllClassLevelAnnotations(AnnotatedChild.class);
	}
	
	public static void main(String[] args) {
		printAllAnnotationsForAnnotatedClass();
		checkIneritedAnnotation();
	}
	
}
